using BuildingBlocks.Abstractions.EventBase;
using BuildingBlocks.Abstractions.Permissions;
using BuildingBlocks.Infrastructure.Email;
using BuildingBlocks.Infrastructure.EventBus.RabbitMQ;
using Identity.Application;
using Identity.Application.Contracts.Common;
using Identity.Application.Contracts.Events;
using Identity.Application.Contracts.Services;
using Identity.Application.PermissionKeyResourceIds.Interfaces;
using Identity.Application.Permissions.Interfaces;
using Identity.Application.RolePermissions.Interfaces;
using Identity.Infrastructure.Caching;
using Identity.Infrastructure.EventHandlers;
using Identity.Infrastructure.HostedServices;
using Identity.Infrastructure.Persistence;
using Identity.Infrastructure.Persistence.IdentityService;
using Identity.Infrastructure.Persistence.ReadServices;
using Identity.Infrastructure.Persistence.Repositories;
using Identity.Infrastructure.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;


namespace Identity.Infrastructure;


public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddIdentityInfrastructure(this IServiceCollection services, IConfiguration configuration)
    {

        services.AddDbContext<ApplicationDbContext>(options =>
        {
            options.UseNpgsql(configuration.GetConnectionString("Default"));
            options.UseOpenIddict(); // 使 OpenIddict 能在 EF Core 上工作
        });
        services.Configure<BaseUrlOptions>(configuration.GetSection("Frontend:BaseUrl"));
        services.AddEmailModule(configuration);

        services.AddScoped<IUserService, UserService>();
        services.AddScoped<IRoleService, RoleService>();
        services.AddScoped<IUserRoleService, UserRoleService>();
        services.AddScoped<IEmailService,EmailService>();
        services.AddEventBus(configuration);
        services.AddSingleton<IRedisService>(sp =>
        {
            var config = configuration.GetConnectionString("Redis");
            return new RedisService(config!);
        });

        services.Configure<JwtOptions>(configuration.GetSection("JwtOptions"));
        services.AddSingleton(sp =>
        {
            var options = sp.GetRequiredService<Microsoft.Extensions.Options.IOptions<JwtOptions>>().Value;
            return new TokenService(options);
        });
        services.AddSingleton<ITokenService>(sp => sp.GetRequiredService<TokenService>());
        services.AddScoped<IPermissionsReadService, PermissionReadService>();
        services.AddScoped<IPermissionsRepository, PermissionRepository>();
        services.AddScoped<IRolePermissionsReadService, RolePermissionReadService>();
      
        
        services.AddScoped<IUnitOfWork, UnitOfWork>();
        
        services.AddTransient<IIntegrationEventHandler<UserRegisteredEvent>,UserRegisteredEventHandler>();
        services.AddTransient<IIntegrationEventHandler<SendCodeEmailWithResetPasswordEvent>,SendCodeEmailWithResetPasswordEventHandler>();
        services.AddTransient<IIntegrationEventHandler<PermissionRegisteredEvent>, PermissionRegisteredEventHandler>();
        services.AddHostedService<IdentityStartupTasks>();
        services.AddScoped<IPermissionCenterService, PermissionCenterService>();
        services.AddScoped<IPermissionBindingService, PermissionBindingService>();
        
        services.AddScoped<IApiPermissionBindingRepository, PermissionKeyResourceIdRepository>();
        services.AddScoped<IApiPermissionBindingReadService, ApiPermissionBindingReadService>();
        return services;
    }
}
